<?php
/**
* 定义常量， 代表拼音表的路径 
*/
define("PINYIN_TABLE_PATH", "../../includes/classes/pinyin.table");

/**
* 汉字转拼音类
*
* @author  iwind <iwind_php@163.com>
* @version 1.0.0
* @example  echo PinYin::conv("我真的不想你是我不是我的");
* @copyright  可任意传播，复制，修改
*/
class PinYin
{
	/**
	* 拼音表总长度
	*
	* @var integer
	* @access  private
	*/
	var $size;
	
	/**
	* 拼音表每行长度
	*
	* @var integer
	* @access  private
	*/
	var $length;
	
	/**
	* 文件句柄
	*
	* @var resource
	* @access  private
	*/
	var $handle;
	
	/**
	* 结果记录行
	*
	* @var array
	* @access  private
	*/
	var $line;
	
	/**
	* 用于记录查找次数的变量
	*
	* @var integer
	* @access  private
	*/
	var $times = 0;
	
	/**
	* 构造函数
	*
	* @access  public
	*/
	function __construct()
	{
		$this->PinYin();
	}
	
	/**
	* PHP4 默认构造函数
	*
	* @access  public
	*/
	function PinYin()
	{
		$this->handle = fopen(PINYIN_TABLE_PATH, "r");
		$this->length = strlen(fgets($this->handle));
		fseek($this->handle, 0, SEEK_END);
		$this->size = ftell($this->handle);
	}
	
	/**
	* 将一个字符串分隔成一个数组
	*
	* @param string $string 要分隔的字符串
	* @return array 结果数组
	* @access  private
	*/
	function getChars($string)
    {
        preg_match_all("/[\x81-\xfe]?./", $string, $m);
        return $m[0];
    }
    
    /**
    * 给一个拼音加上音标
    *
    * @param string $pinyin 拼音
    * @return string 加上音标的拼音
    * @access  private
    */
	function addTone($pinyin)
	{
		$yuan = array(
						"a"=>array(0, 228, 225, 259, 224, 97), 
						"e"=>array(0, 275, 233, 277, 232, 101), 
						"i"=>array(0, 299, 237, 301, 236, 105), 
						"u"=>array(0, 363, 250, 365, 249, 117),
						"o"=>array(0, 333, 243, 335, 242, 111)
					);	
		$pinyin[2] = trim($pinyin[2]);
		$chars = $this->getChars($pinyin[1]);
		foreach ($chars as $i=>$char)
		{
			if (isset($yuan[$char]))
			{
				$chars[$i] = "&#" . $yuan[$char][$pinyin[2]] . ";";	
				break;
			}	
		}
		return implode("", $chars);
	}
    
	/**
	* 查找一个编码在拼音表里对应的行
	*
	* @param  integer 编码
	* @param integer $start 开始处
	* @param integer $end 结束处
	* @return array 行数据
	* @access  private
	*/
    function seek($code, $start = 0, $end = 0)
    {
    	$this->times ++;
    	if ($this->times > 100)
    	{
    		return false;	
    	}
    	if ($end == 0) $end = $this->size;
    	$mid = ceil(($start + $end)/2);
    	$mid = floor($mid/$this->length) * $this->length;
     	fseek($this->handle, $mid);
    	$line = fgets($this->handle);
    	$array = explode("|", $line);  
    	if ($array[0] > $code)
    	{
    		$this->seek($code, $start, $mid);	
    	}  	
    	else if ($array[0] < $code) 
    	{
    		$this->seek($code, $mid, $end);
    	}
    	else 
    	{
    		$this->line = $array;	
    	}
    }
    
    /**
    * 得到查询到的结果
    *
    * @return array 结果
    * @access  private
    */
    function get()
    {
    	rewind($this->handle);
    	$this->times = 0;
    	$m = $this->line;
    	$this->line = null;
    	return $m;	
    }	
	
    /**
    * 执行将字符串转换成拼音
    *
    * @param string $string 要转换的字符串
    * @return  string 结果字符串
    * @access  public
    */
	function conv($string)
	{
		$obj = new PinYin();
		$chars = $obj->getChars($string);
		$m = array();
		foreach ($chars as $v)
		{
			if (strlen($v) > 1)
			{
				$codes = unpack("S", $v);
				$obj->seek($codes[1]);
				$v1 = $obj->get();	
				if (!empty($v1))
				{
					$v = $obj->addTone($v1);	
				}
			}
			$m[] = $v;	
		}
		return implode(" ", $m);
	}
	
	function getfirstchar($ping)
	{
		return substr($ping[1],0,1);
	}
	
	
		function firstchars($string)
	{
		$obj = new PinYin();
		$chars = $obj->getChars($string);
		$m = array();
		foreach ($chars as $v)
		{
			if (strlen($v) > 1)
			{
				$codes = unpack("S", $v);
				$obj->seek($codes[1]);
				$v1 = $obj->get();	
				if (!empty($v1))
				{
					$v = $obj->getfirstchar($v1);	
				}
			}
			$m[] = $v;	
		}
		$a=str_replace(" ","",implode("", $m));
		return str_replace("	","",$a);
	}
	
}
echo"这是我们的测试页面";
echo PinYin::firstchars("z这是我们的测试页面");

?>